#include <sys/types.h>

#include "./def.h"

#ifdef WINDOWS

#else
#include <unistd.h>
#include <signal.h>
#include <sys/time.h>
#endif


#include <time.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#include "btconfig.h"
#include "btcontent.h"
#include "downloader.h"
#include "peerlist.h"
#include "tracker.h"

#include "./config.h"

#ifndef WINDOWS
#include "sigint.h"
#endif

void usage();
int param_check(int argc, char **argv);


#ifdef WINDOWS

int main(int argc, char** argv)
{
	if( argc < 2 || param_check(argc,argv) < 0 ){
		usage();
		exit(1);
	}

	srand( (unsigned)time(NULL) );
	arg_user_agent = new char[MAX_PF_LEN];
	strcpy(arg_user_agent,PEER_PFX);

	WORD wVersionRequested;
	WSADATA wsaData;
	int err;	
	wVersionRequested = MAKEWORD( 2, 0);	
	err = WSAStartup( wVersionRequested, &wsaData );
	if ( err != 0 ) 
	{
		return -1;
	}

	if( cfg_listen_ip )
		Self.m_sin.sin_addr.s_addr = cfg_listen_ip;

	if( BTCONTENT.InitialFromMI(arg_metainfo_file, arg_save_as) < 0){
		fprintf(stderr,"error,initial meta info failed.\n");
		exit(1);
	}

	if( !arg_flg_exam_only && !arg_flg_check_only){
		if(WORLD.Initial_ListenPort() < 0){
			fprintf(stderr,"warn, you couldn't accept connection.\n");
		}else 
			printf("Listen on: %d\n",cfg_listen_port);

		Tracker.Initial();

		Downloader();
	}
	return 0;
}

#else

void Random_init()
{
  struct timeval tv; 
  gettimeofday(&tv,(struct timezone*) 0);
  unsigned int seed = tv.tv_usec + tv.tv_sec + getpid();
  return srandom(seed);
}

int main(int argc, char **argv)
{

  Random_init();
  arg_user_agent = new char[MAX_PF_LEN];
  strcpy(arg_user_agent,PEER_PFX);
    
  if( argc < 2 || param_check(argc,argv) < 0 ){
    usage();
    exit(1);
  }

  if( arg_flg_make_torrent ){
    if( !arg_announce ){ fprintf(stderr,"please use -u to specify a announce url!\n"); exit(1);}
    if( !arg_save_as ){ fprintf(stderr,"please use -s to specify a metainfo file name!\n"); exit(1);}
    if( BTCONTENT.InitialFromFS(arg_metainfo_file, arg_announce,  arg_piece_length) < 0 ||
	BTCONTENT.CreateMetainfoFile(arg_save_as) < 0){
      fprintf(stderr,"create metainfo failed.\n");
      exit(1);
    }
    printf("create metainfo file %s successful.\n", arg_save_as);
    exit(0);
  }
  
  if( BTCONTENT.InitialFromMI(arg_metainfo_file, arg_save_as) < 0){
    fprintf(stderr,"error,initial meta info failed.\n");
    exit(1);
  }

  if( !arg_flg_exam_only && !arg_flg_check_only){
    if(WORLD.Initial_ListenPort() < 0){
      fprintf(stderr,"warn, you couldn't accept connection.\n");
    }else 
      printf("Listen on: %d\n",cfg_listen_port);

	Tracker.Initial();

	signal(SIGPIPE,SIG_IGN);
    signal(SIGINT,sigint_catch);
    Downloader();
  }

  exit(0);
}

#endif

int param_check(int argc, char **argv)
{
	for (int i=1;i<argc;i++)
	{
		if( strcmp("-i",argv[i])==0 && i<argc-1 ){
			i++;
			cfg_listen_ip=inet_addr(argv[i]);
		}
		else if ( strcmp("-s",argv[i])==0 && i<argc-1 )
		{
			i++;
			arg_save_as=new char[strlen(argv[i])+1];
			if (!arg_save_as)
				return -1;
			strcpy(arg_save_as,argv[i]);
		}
		else{
			if (i==argc-1)
			{
				arg_metainfo_file=new char[strlen(argv[i])+1];
				if(!arg_metainfo_file)
					return -1;
				strcpy(arg_metainfo_file,argv[i]);
			}
			else
				return -1;
		}
	}
	return 0;

}

void usage()
{

  fprintf(stderr,"Copyright: YuHong(992126018601033)");
  fprintf(stderr,"modified by YaoWang");
  fprintf(stderr,"\nWARNING: THERE IS NO WARRANTY FOR CTorrent. USE AT YOUR OWN RISK!!!\n");
  fprintf(stderr,"\nGeneric Options:\n");
  fprintf(stderr,"-s save_as\tSave file/directory/metainfo as... \n");
  fprintf(stderr,"-i local ip\n");

/*
  fprintf(stderr,"-h/-H\t\tShow this message.\n");
  fprintf(stderr,"-x\t\tDecode metainfo(torrent) file only, don't download.\n");
  fprintf(stderr,"-c\t\tCheck exist only. don't download.\n");
  fprintf(stderr,"\nDownload Options:\n");
  fprintf(stderr,"-e int\t\tExit while seed <int> hours later. (default 72 hours)\n");
  fprintf(stderr,"-p port\t\tListen port. (default 2706 -> 2106)\n");
  
  fprintf(stderr,"-C cache_size\tCache size,unit MB. (default 16MB)\n");
  fprintf(stderr,"-f\t\tForce seed mode. skip hash check at startup.\n");
  fprintf(stderr,"-b bf_filename\tBit field filename. (use it carefully)\n");
  fprintf(stderr,"-M max_peers\tMax peers count.\n");
  fprintf(stderr,"-m min_peers\tMin peers count.\n");
  fprintf(stderr,"-B rate\t\tMax bandwidth (unit KB/s)\n");
  fprintf(stderr,"-P peer_id\tSet Peer ID ["PEER_PFX"]\n");
  fprintf(stderr,"\nMake metainfo(torrent) file Options:\n");
  fprintf(stderr,"-t\t\tWith make torrent. must specify this option.\n");
  fprintf(stderr,"-u url\t\tTracker's url.\n");
  fprintf(stderr,"-l piece_len\tPiece length.(default 262144)\n");
  fprintf(stderr,"\neg.\n");
  fprintf(stderr,"hong> ctorrent -s new_filename -e 12 -C 32 -p 6881 eg.torrent\n\n");
  fprintf(stderr,"home page: http://ctorrent.sourceforge.net/\n");
  fprintf(stderr,"bug report: %s\n\n",PACKAGE_BUGREPORT);
*/
}
